import React from 'react';
import {
    AtomicBlockUtils,
    Editor,
    EditorState,
    Entity,
    RichUtils,
    convertFromRaw,
    convertToRaw,
  } from 'draft-js';
import axios from 'axios';
import util from 'util';
import { connect } from 'react-redux'
import { loadGamePost } from './actions';
import CommentList from '../CommentList'
import CommentEditor from '../CommentEditor'
import '../../static/css/Draft.css';
import './RichEditor.css'


class GamePostDisplay extends React.Component {
  constructor(props) {
    super(props);
    

    this.state = {
      editorState: EditorState.createEmpty()
    };

    this.focus = () => this.refs.editor.focus();
    this.onChange = (editorState) => this.setState({editorState});
    this.logState = () => {
      const content = this.state.editorState.getCurrentContent();
      console.log( JSON.stringify(convertToRaw(content)) );
    };

    this.handleKeyCommand = this._handleKeyCommand.bind(this);
    this.addMedia = this._addMedia.bind(this);
    this.addAudio = this._addAudio.bind(this);
    this.addImage = this._addImage.bind(this);
    this.addVideo = this._addVideo.bind(this);

    this.toggleBlockType = (type) => this._toggleBlockType(type);
    this.toggleInlineStyle = (style) => this._toggleInlineStyle(style);

    // Handle Uploading Image Logic
    this.handleUploadSubmit = this._handleUploadSubmit.bind(this);
    this.addUploadImage = this._addUploadImage.bind(this);
    this.addUpload_to_Editor = this._addUpload_to_Editor.bind(this);
  }

  

  componentDidMount() {

    console.log(this.props.params.post_id);

    var that = this

    axios.get('/api/gamePost/getGamePostByID', {
        params: {
          post_id: this.props.params.post_id
        }
      })
      .then(function (response) {
        var restoredRaw = JSON.parse(response.data.content);
        var restoredContentState = convertFromRaw(restoredRaw);

        var newEditorSate = EditorState.createWithContent(restoredContentState);
        that.setState({editorState : newEditorSate}, function () {
          console.log("Setted the State");
        });
        // console.log(JSON.stringify(restoredContentState));
        // console.log(JSON.stringify({editorSate : newEditorSate}));
      })
      .catch(function (error) {
        console.log(error);
      }); 

    return    
  }  




  
  _handleKeyCommand(command) {
    const {editorState} = this.state;
    const newState = RichUtils.handleKeyCommand(editorState, command);
    if (newState) {
      this.onChange(newState);
      return true;
    }
    return false;
  }

  // Rich Text Part
  _toggleBlockType(blockType) {
    this.onChange(
      RichUtils.toggleBlockType(
        this.state.editorState,
        blockType
      )
    );
  }

  _toggleInlineStyle(inlineStyle) {
    this.onChange(
      RichUtils.toggleInlineStyle(
        this.state.editorState,
        inlineStyle
      )
    );
  }

  // Media Part
  _addMedia(type) {
    const src = window.prompt('Enter a URL');
    if (!src) {
      return;
    }

    const entityKey = Entity.create(type, 'IMMUTABLE', {src});

    return AtomicBlockUtils.insertAtomicBlock(
      this.state.editorState,
      entityKey,
      ' '
    );
  }

  // Handle Uploading Image Logic
  _addUpload_to_Editor(img_id) {
    const src = '/api/upload/' + img_id
    console.log('adding this image to the Editor: ' + src)

    const entityKey = Entity.create('image', 'IMMUTABLE', {src});

    return AtomicBlockUtils.insertAtomicBlock(
      this.state.editorState,
      entityKey,
      ' '
    );
  }  

  _addAudio() {
    this.onChange(this._addMedia('audio'));
  }

  _addImage() {
    this.onChange(this._addMedia('image'));
  }

  _addUploadImage(img_id) {
    this.onChange(this._addUpload_to_Editor(img_id));
  }

  _addVideo() {
    this.onChange(this._addMedia('video'));
  }


  // Handle Uploading Image Logic
  _handleUploadSubmit(e) {
    var self = this;
    e.preventDefault();
    // TODO: do something with -> this.state.file
    let file = this.refs.file_input.files[0]  
    // console.log(file)
    const data = new FormData()
    data.append('file', file)
    axios.post('/api/upload', data)
            .then(function (res) {
              console.log('upload success, image id:')
              console.log(util.inspect(res.data, false, null))
              self._addUploadImage(res.data)
            })
            .catch(function (err) {
              console.log('error' + err.message)
            })
  }

  render() {


    const {editorState} = this.state;
    // If the user changes block type before entering any text, we can
    // either style the placeholder or hide it. Let's just hide it now.
    let className = 'RichEditor-editor';
    var contentState = editorState.getCurrentContent();
    if (!contentState.hasText()) {
      if (contentState.getBlockMap().first().getType() !== 'unstyled') {
        className += ' RichEditor-hidePlaceholder';
      }
    }

    return (
      <div className="RichEditor-root" style={styles.root}>

        <div style={styles.editor} onClick={this.focus}>
          <Editor
            blockStyleFn={getBlockStyle}
            blockRendererFn={mediaBlockRenderer}
            customStyleMap={styleMap}
            editorState={this.state.editorState}
            handleKeyCommand={this.handleKeyCommand}
            onChange={this.onChange}
            placeholder="Enter some text..."
            ref="editor"
            spellCheck={true}
            readOnly={true}
          />
        </div>

        <CommentList post_id = {this.props.params.post_id}/>

        <CommentEditor post_id = {this.props.params.post_id}/>

      </div>
    );
  }
}

// Custom overrides for "code" style.
const styleMap = {
  CODE: {
    backgroundColor: 'rgba(0, 0, 0, 0.05)',
    fontFamily: '"Inconsolata", "Menlo", "Consolas", monospace',
    fontSize: 16,
    padding: 2,
  },
};

function getBlockStyle(block) {
  switch (block.getType()) {
    case 'blockquote': return 'RichEditor-blockquote';
    default: return null;
  }
}

class StyleButton extends React.Component {
  constructor() {
    super();
    this.onToggle = (e) => {
      e.preventDefault();
      this.props.onToggle(this.props.style);
    };
  }

  render() {
    let className = 'RichEditor-styleButton';
    if (this.props.active) {
      className += ' RichEditor-activeButton';
    }

    return (
      <span className={className} onMouseDown={this.onToggle}>
        {this.props.label}
      </span>
    );
  }
}

const BLOCK_TYPES = [
  {label: 'H1', style: 'header-one'},
  {label: 'H2', style: 'header-two'},
  {label: 'H3', style: 'header-three'},
  {label: 'H4', style: 'header-four'},
  {label: 'H5', style: 'header-five'},
  {label: 'H6', style: 'header-six'},
  {label: 'Blockquote', style: 'blockquote'},
  {label: 'UL', style: 'unordered-list-item'},
  {label: 'OL', style: 'ordered-list-item'},
  {label: 'Code Block', style: 'code-block'},
];

const BlockStyleControls = (props) => {
  const {editorState} = props;
  const selection = editorState.getSelection();
  const blockType = editorState
    .getCurrentContent()
    .getBlockForKey(selection.getStartKey())
    .getType();

  return (
    <div className="RichEditor-controls">
      {BLOCK_TYPES.map((type) =>
        <StyleButton
          key={type.label}
          active={type.style === blockType}
          label={type.label}
          onToggle={props.onToggle}
          style={type.style}
        />
      )}
    </div>
  );
}


var INLINE_STYLES = [
  {label: 'Bold', style: 'BOLD'},
  {label: 'Italic', style: 'ITALIC'},
  {label: 'Underline', style: 'UNDERLINE'},
  {label: 'Monospace', style: 'CODE'},
];

const InlineStyleControls = (props) => {
  var currentStyle = props.editorState.getCurrentInlineStyle();
  return (
    <div className="RichEditor-controls">
      {INLINE_STYLES.map(type =>
        <StyleButton
          key={type.label}
          active={currentStyle.has(type.style)}
          label={type.label}
          onToggle={props.onToggle}
          style={type.style}
        />
      )}
    </div>
  );
}


// Media Part
function mediaBlockRenderer(block) {
  if (block.getType() === 'atomic') {
    return {
      component: Media,
      editable: false,
    };
  }

  return null;
}

const Audio = (props) => {
  return <audio controls src={props.src} style={styles.media} />;
};

const Image = (props) => {
  return <img src={props.src} style={styles.media} />;
};

const Video = (props) => {
  return <video controls src={props.src} style={styles.media} />;
};

const Media = (props) => {
  const entity = Entity.get(props.block.getEntityAt(0));
  const {src} = entity.getData();
  const type = entity.getType();

  let media;
  if (type === 'audio') {
    media = <Audio src={src} />;
  } else if (type === 'image') {
    media = <Image src={src} />;
  } else if (type === 'video') {
    media = <Video src={src} />;
  }

  return media;
};

const styles = {
  root: {
    fontFamily: '\'Georgia\', serif',
    padding: 20,
    width: 600,
  },
  buttons: {
    marginBottom: 10,
  },
  editor: {
    border: '1px solid #ccc',
    cursor: 'text',
    minHeight: 80,
    padding: 10,
  },
  button: {
    marginTop: 10,
    textAlign: 'center',
  },
  media: {
    width: '100%',
  },
};


function mapStateToProps(state, ownProps) {
  const {
    gamePostEditor: { saved, saving },
  } = state

  return {
    saved,
    saving
  }
}


function mapDispatchToProps(dispatch) {
  return {
    onloadGamePost: (page_id) => { dispatch(loadGamePost(page_id)) },
    dispatch,
  }
}


module.exports = connect(mapStateToProps, mapDispatchToProps)(GamePostDisplay)